﻿using BusinessRepository;
using EcmaScript.NET;
using System;
using System.Collections.Generic;
using System.Data;
using System.Threading.Tasks;

using BusinessEntity;
using System.Transactions;
using learun.util;

namespace BusinessRule
{
    public class TranstionRule
    {
        public async static Task<bool> GetExist(string strsql)
        {
            DataTable dts = await ProcessSql(strsql);
            bool exists = false;
            for (int i = 0; i < dts.Rows.Count; i++)
            {
                exists = true;
                break;
            }
            return exists;
        }

        public async static Task<T> FindEntityByKey<T>(string kid) where T : class
        {
            //string strsql = "select * from View_ProHTBGLists where gsid = '" + strgsid + "'";

            return await new RepositoryFactory().BaseRepository().FindEntityByKey<T>(kid);
        }

        public async static Task<T> FindEntity<T>(object obj) where T : class
        {
            return await new RepositoryFactory().BaseRepository().FindEntity<T>(obj);
        }

        public async static Task<T> FindEntity<T>(string obj) where T : class
        {
            return await new RepositoryFactory().BaseRepository().FindEntity<T>(obj);
        }

        public async static Task<DataTable> ProcessSql(string strsql)
        {
            return await new RepositoryFactory().BaseRepository().FindTable(strsql);
        }

        public async static Task<IEnumerable<dynamic>> ProcessSqld(string strsql)
        {
            return await new RepositoryFactory().BaseRepository().FindList(strsql);
        }



        public static bool GetRunListTrans2(params IRepository[] IRepositorys)
        {
            using (TransactionScope transScope = new TransactionScope())
            {
                try
                {
                    //sc1.Transaction = sqlTran1;
                    //sc1.ExecuteScalar();

                    //sc2.Transaction = sqlTran2;
                    //sc2.ExecuteScalar();

                    for (int i = 0; i < IRepositorys.Length; i++)
                    {
                        IRepositorys[i].BeginTrans();
                    }



                }
                catch (System.Data.SqlClient.SqlException ex)
                {
                    //sqlTran1.Rollback();
                    //sqlTran2.Rollback();
                    //s1.Close();//如果不增加数据库事务，连接关闭时，数据会写入数据库
                    //s2.Close();
                    //return;
                    for (int i = 0; i < IRepositorys.Length; i++)
                    {
                        IRepositorys[i].Rollback();
                    }

                    return false;
                }
                //sqlTran1.Commit();
                //sqlTran2.Commit();
                for (int i = 0; i < IRepositorys.Length; i++)
                {
                    IRepositorys[i].Commit();
                }
                transScope.Complete();

                return true;
                //s1.Close();
                //s2.Close();
            }
        }

        public static bool GetRunListTrans(List<string> list)
        {
            IRepository repository = new RepositoryFactory().BaseRepository();


            repository.BeginTrans();

            try
            {
                //循环执行
                for (int i = 0; i < list.Count; i++)
                {
                    repository.ExecuteSql(list[i]);
                }

                repository.Commit();

                return true;
            }
            catch (Exception)
            {
                repository.Rollback();

                return false;
            }
        }

        public static async Task<bool> GetRunListTransAsync(List<string> list)
        {
            IRepository repository = new RepositoryFactory().BaseRepository();


            repository.BeginTrans();

            try
            {
                //循环执行
                for (int i = 0; i < list.Count; i++)
                {
                    await repository.ExecuteSql(list[i]);


                }

                repository.Commit();

                return true;
            }
            catch (Exception)
            {
                repository.Rollback();

                return false;
            }
        }

        public static async Task<bool> GetRunActionTransAsync(Func<IRepository, Task<bool>> runs)
        {
            IRepository repository = new RepositoryFactory().BaseRepository();

            repository.BeginTrans();

            try
            {
                await runs(repository);

                repository.Commit();

                return true;
            }
            catch (Exception ex)
            {


                repository.Rollback();

                throw new Exception(ex.Message);
                //throw Exception("");// false;
            }
        }
    }

    public class Transaction
    {
        List<IRepository> lists = null;
        Dictionary<string, IRepository> dics = null;
        public Transaction()
        {
            //this.lists = new  List<IRepository>();
            dics = new Dictionary<string, IRepository>();
        }

        public IRepository AddIRepository(string name = "0")
        {
            //开启事务
            IRepository repository = new RepositoryFactory().BaseRepository();
            repository.BeginTrans();

            //lists.Add(repository);
            dics.Add(name, repository);

            return repository;
        }

        public IRepository AddIRepository(string conn, string dbType, string name = "0")
        {
            string strconn = ConfigHelper.GetAppSettings("ServerOp:"+ conn);
            string strdbType = ConfigHelper.GetAppSettings("ServerOp:"+ dbType);
            //开启事务
            IRepository repository = new RepositoryFactory().BaseRepository(strconn, strdbType);
            repository.BeginTrans();

            //lists.Add(repository);
            dics.Add(name, repository);
            return repository;
        }

        public async Task<bool> GetRunActionTransAsync(Func<IRepository, Task<bool>> runs, string name = "0")
        {
            try
            {
                IRepository repository = dics[name];

                if (null == repository)
                {
                    throw new Exception("名称不存在");
                }

                await runs(repository);


                return true;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }


        public bool Commit()
        {
            bool flag;
            bool flag2 = true;
            try
            {
                foreach (var item in dics)
                {
                   item.Value.CommitMulti();
                }
 
                flag = flag2;
            }
            catch (Exception exception)
            {
                foreach (var item in dics)
                {
                    item.Value.RollbackMulti();
                }
                throw exception;
            }
            finally
            {
                foreach (var item in dics)
                {
                    item.Value.CloseMulti();
                }
            }
            return flag;
        }

        public void RollBack()
        {
            try
            {
                foreach (var item in dics)
                {
                    item.Value.RollbackMulti();
                }
            }
            finally
            {
                foreach (var item in dics)
                {
                    item.Value.CloseMulti();
                }
            }
        }


    }
}
